<?php
/**
 * 订单管理
 * @Author sunge
 * @DateTime  2019-06-19
 */
namespace App\Http\Controllers\Admin;

use App\Exceptions\FormException;
use App\Http\Controllers\Controller;
use App\Models\Goods;
use App\Jobs\ExportData;
use App\Models\Order;
use App\Models\OrderGoods;
use App\Models\UserAccount;
use App\Models\AccountLog;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Services\DreamBoxService;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Cache;


class OrderController extends Controller
{
    /**
     * 订单列表
     * @param Request $request
     * @param $id 订单类型
     * @return View
     */
    public function getList(Request $request, $id)
    {
        $today = date("Y-m-d");
        $week = date('Y-m-d', strtotime('-7 days'));
        $month = date("Y-m-d", mktime(0, 0, 0, date("m"), 1, date("Y")));
        $lastMoney = date("Y-m-d", mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
        $statusarr = [
            Order::STATUS_WAIT_COLLECT,
            Order::STATUS_SUCCESS,
            Order::STATUS_WAIT_DELIVER,
            Order::STATUS_AFTER_ING,
            Order::STATUS_WAIT_GET,
        ];
        $saleMoney['Today'] = Order::where('created_at', ">", $today)->whereIn("status", $statusarr)->sum('real_pay');
        $saleMoney['LastWeek'] = Order::where('created_at', ">", $week)->whereIn("status", $statusarr)->sum('real_pay');
        $saleMoney['Month'] = Order::where('created_at', ">", $month)->whereIn("status", $statusarr)->sum('real_pay');
        $saleMoney['LastMonth'] = Order::where('created_at', ">", $lastMoney)->where('created_at', "<", $month)->whereIn("status", $statusarr)->sum('real_pay');
        $saleMoney['Today'] = round($saleMoney['Today'], 2);
        $saleMoney['LastWeek'] = round($saleMoney['LastWeek'], 2);
        $saleMoney['Month'] = round($saleMoney['Month'], 2);
        $saleMoney['LastMonth'] = round($saleMoney['LastMonth'], 2);

        $order['Today'] = Order::where('created_at', ">", $today)->whereIn("status", $statusarr)->count();
        $order['LastWeek'] = Order::where('created_at', ">", $week)->whereIn("status", $statusarr)->count();
        $order['Month'] = Order::where('created_at', ">", $month)->whereIn("status", $statusarr)->count();
        $order['LastMonth'] = Order::where('created_at', ">", $lastMoney)->where('created_at', "<", $month)->whereIn("status", $statusarr)->count();

        $sale['Today'] = OrderGoods::whereHas('Order', function ($query) use ($today, $statusarr) {
            $query->where('created_at', ">", $today)->wherein("status", $statusarr);
        })->sum('amount');

        $sale['LastWeek'] = OrderGoods::whereHas('Order', function ($query) use ($week, $statusarr) {
            $query->where('created_at', ">", $week)->wherein("status", $statusarr);
        })->sum('amount');

        $sale['Month'] = OrderGoods::whereHas('Order', function ($query) use ($month, $statusarr) {
            $query->where('created_at', ">", $month)->wherein("status", $statusarr);
        })->sum('amount');
        $sale['LastMonth'] = OrderGoods::whereHas('Order', function ($query) use ($lastMoney, $statusarr, $month) {
            $query->where('created_at', ">", $lastMoney)->where('created_at', "<", $month)->wherein("status", $statusarr);
        })->sum('amount');

        $departmentList = DB::table('user_department')
            ->get()
            ->mapWithKeys(function ($item) {
                return [$item->id => $item->department_name];
            });
        $payload = $request->all(['keyword', 'time', 'type', 'status', 'pay_type', 'user_type']);
        $table = Order::with(['OrderGoods', 'userInfo', 'userInfo.inviteUserInfo'])->orderBy('updated_at', 'desc')
            ->when($keywords = array_get($payload, 'keyword'), function ($query) use ($keywords) {
                $query->where(function ($query) use ($keywords) {
                    $query->Where('online_order', 'like', "%$keywords%")
                        ->orWhere('user_name', 'like', "%$keywords%")
                        ->orWhere(function ($query) use ($keywords) {
                            $query->WhereHas('userInfo', function ($query) use ($keywords) {
                                $query->where('realname', 'like', "%$keywords%")
                                    ->orWhere('phone', 'like', "%$keywords%");
                            });
                        })
                        ->orWhere('user_phone', 'like', "%$keywords%");
                });
            })
            ->when($user_type = array_get($payload, 'user_type'), function ($query) use ($user_type) {
                $query->WhereHas('userInfo.inviteUserInfo', function ($query) use ($user_type) {
                    $query->where('user_type', $user_type);
                });
            })
            ->when($time = array_get($payload, 'time'), function ($query) use ($time) {
                $time = explode(' - ', $time);
                $time[1] = Carbon::parse($time[1])->addDay()->toDateString();
                $query->whereBetween('created_at', $time);
            })
            ->when($type = array_get($payload, 'type'), function ($query) use ($type) {
                $query->where('order_type', $type);
            })
            ->when($status = array_get($payload, 'status'), function ($query) use ($status) {
                $query->where('status', $status);
            }, function ($query) use ($id) {
                if ($id == 0) {
                    $query->where('status', "!=", Order::STATUS_CANCEL);
                } elseif ($id == 5) {
                    $query->wherein('status', [Order::STATUS_CANCEL, Order::STATUS_REFUND, Order::STATUS_SUCCESS]);
                } else {
                    $query->where('status', $id);
                }

            })

            ->when($pay_type = array_get($payload, 'pay_type'), function ($query) use ($pay_type) {
                $query->where('pay_type', $pay_type);
            })->paginate($request->get('limit', 10));

        $tabledata = $table->map(function ($item) use ($table,$departmentList) {
            if ($item->user_region) {
                $region = '';
                foreach (json_decode($item->user_region) as $key => $value) {
                    $region .= $value . " ";
                }
                $item->user_region = $region;
            }
            $item->inviteUserInfo_realname = $item->userInfo ? ($item->userInfo->inviteUserInfo? $item->userInfo->inviteUserInfo->realname : "") :"";
            $item->inviteUserInfo_id = $item->userInfo ? ($item->userInfo->inviteUserInfo? $item->userInfo->inviteUserInfo->id : "") :"";
            $item->inviteUserInfo_department = $item->userInfo ? ($item->userInfo->inviteUserInfo? (array_key_exists($item->userInfo->inviteUserInfo->department,$departmentList) ? $departmentList[$item->userInfo->inviteUserInfo->department]:"") : "") :"";

            return $item;
        });
        $page = isset($page) ? $request['page'] : 1;
        $table = $table->appends(array(
            'keyword'  => array_get($payload, 'keyword'),
            'time'     => array_get($payload, 'time'),
            'type'     => array_get($payload, 'type'),
            'status'   => array_get($payload, 'status'),
            'pay_type' => array_get($payload, 'pay_type'),
            'page'     => $page
        ));
        $total = $table->total();
        $totalmoney = $table->sum('real_pay');
        return view('Admin/order/index', compact('id', 'saleMoney', 'order', 'sale', 'table', 'tabledata', 'payload', 'total', 'totalmoney', 'departmentList'));
    }

    /**
     * 订单详情
     * @param Request $request
     * @param $id 订单类型
     * @return View
     */
    public function detail(Request $request, $id)
    {
        $order = Order::with(['OrderGoods', 'userInfo',])->findOrFail($id);
        $goods = $order->OrderGoods;
        $user = $order->User;
        $departmentList = DB::table('user_department')
            ->get()
            ->mapWithKeys(function ($item) {
                return [$item->id => $item->department_name];
            });
        $norm = DB::table("goods_norm")
            ->get()
            ->mapWithKeys(function ($item) {
                return [$item->id => $item->name];
            });
        $adminer = DB::table("adminer")
            ->get()
            ->mapWithKeys(function ($item) {
                return [$item->id => $item->username];
            });
        return view('Admin/order/detail', compact('order', 'goods', 'user', 'id', 'departmentList', 'norm', 'adminer'));
    }

    /**
     * 发货弹出框
     * @param $id
     * @return
     */
    public function deliver($id)
    {
        $order = Order::findOrFail($id);

        $region = '';
        foreach (json_decode($order->user_region) as $key => $value) {
            $region .= $value . " ";
        }
        $order->user_region = $region;
        return view('Admin/order/deliver', compact('order', 'id'));
    }

    /**
     * 发货状态更新
     * @param Request $request
     * @throws
     * @return Json
     */
    public function deliverSave(Request $request)
    {
        $id = $request->input("id");
        $express_name = $request->input("express_name");
        $express_order = $request->input("express_order");
        \DB::beginTransaction();
        try {
            $model = Order::findOrFail($id);
            $model->status = Order::STATUS_WAIT_COLLECT;
            $model->send_time = date("Y-m-d H:i:s");
            $model->send_user = Auth::guard('admin')->user()->id;
            $model->send_type = Order::POST;
            $model->express_name = $express_name;
            $model->express_order = $express_order;
            $model->updated_at = date("Y-m-d H:i:s");
            $model->save();
        } catch (\Exception $exception) {
            \DB::rollBack();
            throw new FormException(App::environment('local') ? $exception->getMessage() : '发货失败');
        }
        \DB::commit();
        return $this->getResponseSuccess('发货成功');

    }

    /**
     * 退款 更新状态
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws FormException
     */

    public function refund(Request $request)
    {
        $id = $request->input("id");
        \DB::beginTransaction();
        try {
            $model = Order::with("userInfo")->findOrFail($id);
            $account = UserAccount::where('user_id', $model->userinfo->id)->sharedLock()->firstOrFail();
            if ($model->pay_type == Order::PAY_TYPE_BABEI) {
                $account->money_recharge += $model->postage;
                $account->save();

                $accountLog = new AccountLog();
                $accountLog->user_id = $model->userinfo->id;
                $accountLog->account_type = AccountLog::EIGHT_COIN;
                $accountLog->money = $model->real_pay;
                $accountLog->balance = $account->money_eight_consh + $model->real_pay;
                $accountLog->type = AccountLog::REFUND_TYPE;
                $accountLog->status = AccountLog::SUCCESS;
                $accountLog->remark = '后台订单售后退款';
                $accountLog->return_to = AccountLog::EIGHT_COIN;
                $accountLog->created_at = Carbon::now()->toDateTimeString();
                $accountLog->save();

                $box_service = new DreamBoxService();
                $coin = $box_service->coin_refund($model->userinfo->openid, $model->online_order);
                if ($coin != 1) {
                    \DB::rollBack();
                    return $this->getResponse($coin);
                }
            } elseif ($model->pay_type == Order::PAY_TYPE_SELF) {
                $account->money_recharge += $model->real_pay;
                $account->save();

                $accountLog = new AccountLog();
                $accountLog->user_id = $model->userinfo->id;
                $accountLog->account_type = AccountLog::EIGHT_BALANCE;
                $accountLog->money = $model->real_pay;
                $accountLog->balance = $account->money_recharge + $model->real_pay;
                $accountLog->type = AccountLog::REFUND_TYPE;
                $accountLog->status = AccountLog::SUCCESS;
                $accountLog->remark = '后台订单售后退款';
                $accountLog->return_to = AccountLog::EIGHT_BALANCE;
                $accountLog->created_at = Carbon::now()->toDateTimeString();
                $accountLog->save();

            } else {

            }
            $model->return_time = date("Y-m-d H:i:s");
            $model->return_money = $model->real_pay;
            $model->return_user = $model->userinfo->id;
            $model->return_creater = Auth::guard('admin')->user()->id;
            $model->status = Order::STATUS_REFUND;
            $model->updated_at = date("Y-m-d H:i:s");
            $model->save();
        } catch (\Exception $exception) {
            \DB::rollBack();
            throw new FormException(App::environment('local') ? $exception->getMessage() : '退款失败');
        }
        \DB::commit();
        /* 清楚前端缓存 */
        Cache::store('redis')->forget('user:info_' . $model->userinfo->id);

//        if($model->order_type == Order::TYPE_MACHINE or $model->order_type == Order::TYPE_SCANCODE){
        $service = new \App\Services\ReportService($model->online_order, \App\Services\ReportService::RequestCodeRefund);
        dispatch(new \App\Jobs\HtReportApi($service));
//        }

        return $this->getResponseSuccess('退款成功');
    }

    /**
     * 驳回 更新状态
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws FormException
     */
    public function reject(Request $request)
    {
        $id = $request->input('id');
        DB::beginTransaction();
        try {
            $model = Order::findOrFail($id);
            $model->status = $model->saled_status;
            $model->updated_at = date("Y-m-d H:i:s");
            $model->save();

        } catch (\Exception $exception) {

            DB::rollBack();
            throw new FormException(App::environment('local') ? $exception->getMessage() : '设置失败');

        }

        DB::commit();
        return $this->getResponseSuccess('设置成功');
    }

    /**
     * 导出excel
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function export(Request $request)
    {
        $payload = $request->all();
        $filename = $request->input('filename', 'demo.csv');
        $filename = rtrim($filename, '.csv') . '.csv';
        $id = $payload['id'];
        if (Storage::disk('exports')->exists($filename))
            return $this->getResponse('文件已存在，请重新输入', [], 302, url('admin/user/index'));
        //判断前台是否有选择
        if (empty($payload['ids'])) {
            /* 获取查询条件 */
            $payload = $request->all();
            $preData = Order::with(['OrderGoods', 'userInfo', 'userInfo.inviteUserInfo'])->orderBy('updated_at', 'desc')
                ->when($keywords = array_get($payload, 'keywords'), function ($query) use ($keywords) {
                    $query->where(function ($query) use ($keywords) {
                        $query->orWhere('online_order', 'like', "%$keywords%")
                            ->orWhere('user_name', 'like', "%$keywords%")
                            ->orWhere('user_phone', 'like', "%$keywords%");
                    });
                })
                ->when($user_type = array_get($payload, 'user_type'), function ($query) use ($user_type) {
                    $query->WhereHas('userInfo.inviteUserInfo', function ($query) use ($user_type) {
                        $query->where('user_type', $user_type);
                    });
                })
                ->when($time = array_get($payload, 'time'), function ($query) use ($time) {
                    $time = explode(' - ', $time);
                    $time[1] = Carbon::parse($time[1])->addDay()->toDateString();
                    $query->whereBetween('created_at', $time);
                })
                ->when($type = array_get($payload, 'type'), function ($query) use ($type) {
                    $query->where('order_type', $type);
                })
                ->when($status = array_get($payload, 'status'), function ($query) use ($status) {
                    $query->where('status', $status);
                }, function ($query) use ($id) {
                    $query->where('status', $id);
                })
                ->when($pay_type = array_get($payload, 'pay_type'), function ($query) use ($pay_type) {
                    $query->where('pay_type', $pay_type);
                })
                ->get();
        } else {
            //有选择
            $preData = Order::with(['OrderGoods', 'User'])->whereIn('id', $payload['ids'])->orderBy('updated_at', 'desc')->get();
        };
        if (count($preData) == 0) {
            return $this->getResponse('导出不能为空，请重新尝试', [], 302, url('admin/user/index'));
        }
        $departmentList = DB::table('user_department')
            ->get()
            ->mapWithKeys(function ($item) {
                return [$item->id => $item->department_name];
            });

        $data = [];
        $i = 0;
        foreach ($preData as $key => $item) {
            foreach ($item->OrderGoods as $k => $v) {
                $data[$i]['created_at'] = $item->created_at;
                $data[$i]['online_order'] = $item->online_order;
                $data[$i]['user_name'] = $item->user_name;
                $data[$i]['user_phone'] = $item->user_phone;
                $data[$i]['user_address'] = $item->user_address;
                $data[$i]['express_order'] = $item->express_order;
                $data[$i]['photo'] = $v->photo;
                $data[$i]['title'] = $v->title;
                $data[$i]['amount'] = $v->amount;
                $data[$i]['real_pay'] = round($item->real_pay, 2);
                $data[$i]['express_name'] = $item->order_type == Order::TYPE_ONLINE ?
                    (array_key_exists($item->express_name, Order::EXPRESS) ? Order::EXPRESS[$item->express_name] : "") : "不需要配送";
                $data[$i]['pay_type'] = array_key_exists($item->pay_type, Order::PAY_TYPE) ? Order::PAY_TYPE[$item->pay_type] : '';
                $data[$i]['status'] = array_key_exists($item->status, Order::STSTUS) ? Order::STSTUS[$item->status] : '';
                $data[$i]['order_type'] = array_key_exists($item->order_type, Order::TYPE) ? Order::TYPE[$item->order_type] : "";
                $data[$i]['realname'] = $item->userInfo->inviteUserInfo ? $item->userInfo->inviteUserInfo->realname : "";
                $data[$i]['id'] = $item->userInfo->inviteUserInfo ? $item->userInfo->inviteUserInfo->id : "";
                $data[$i]['department'] = $item->userInfo->inviteUserInfo ? array_key_exists($item->userInfo->inviteUserInfo->department, $departmentList) ? $departmentList[$item->userInfo->inviteUserInfo->department] : "" : "";
                $i++;
            }
        }
        /* 定义文件头 */
        $header = [
            'created_at'    => '下单时间',
            'online_order'  => '订单编号',
            'order_type'    => '售卖类型',
            'photo'         => '缩略图',
            'amount'        => '商品数量',
            'title'         => '商品名称',
            'user_name'     => '收货人姓名',
            'user_phone'    => '收货人电话',
            'user_address'  => '收货人地址',
            'real_pay'      => '支付金额',
            'pay_type'      => '支付类型',
            'express_name'  => '快递名称',
            'express_order' => '快递单号',
            'realname'      => '员工姓名',
            'id'            => '员工ID',
            'department'    => '员工部门',
            'status'        => '状态',
        ];

        /* 插入队列 */
        /* 闭包序列化处理 */
        //$serializer = new Serializer();
        dispatch(new ExportData($header, '', '', $filename, $data));
        return $this->getResponse('已加入导出队列', [], 200, url('admin/partner'));
    }

}